
# pyinstaller --icon Heart.ico --onefile --name=ID_Card --add-data "id_card_data.txt;." information_From_ID_Numbers.py

# 使用 PyInstaller 打包时的命令，用于将 Python 脚本打包成单个可执行文件
# --icon 指定图标文件
# --onefile 打包成单个可执行文件
# --name 指定生成的可执行文件名称
# --add-data 添加额外的文件到可执行文件中
# information_From_ID_Numbers.py 是要打包的 Python 脚本
import dlib
import requests  # 用于发送 HTTP 请求
import os  # 用于操作系统相关功能
import subprocess  # 用于运行系统命令
import sys  # 用于访问 Python 解释器的相关信息
import re  # 用于正则表达式匹配
import platform  # 用于获取操作系统信息
import time  # 用于时间相关操作
from datetime import datetime  # 用于日期和时间操作

# 定义一个函数，用于获取资源文件的路径
# 在 PyInstaller 打包后，资源文件会存储在临时目录中，此函数用于正确访问这些文件
def get_resource_path(relative_path):
    try:
        # PyInstaller 创建的临时文件夹路径存储在 _MEIPASS 中
        base_path = sys._MEIPASS
    except Exception:
        # 如果不是打包后的程序，则使用当前工作目录
        base_path = os.path.abspath(".")
    # 返回资源文件的完整路径
    return os.path.join(base_path, relative_path)

# 定义一个函数，用于加载身份证地址数据
# file_path 是数据文件的路径
def load_id_card_data(file_path):
    id_card_dict = {}  # 创建一个空字典用于存储身份证地址数据
    # 打开文件并读取每一行
    with open(file_path, 'r', encoding='utf-8') as file:
        for line in file:
            line = line.strip()  # 去除行首尾的空白字符
            if line:  # 如果行不为空
                # 按照冒号分割代码和地址
                code, address = line.split(':')
                # 将代码和地址存储到字典中
                id_card_dict[code.strip()] = address.strip()
    return id_card_dict  # 返回存储了身份证地址数据的字典

# 定义一个函数，用于代码根据查询地址
# code 是身份证号码的前6位，id_card_dict 是存储地址数据的字典
def query_address_by_code(code, id_card_dict):
    # 使用字典的 get 方法查询地址，如果找不到则返回默认值 "未找到对应的地址"
    return id_card_dict.get(code, "未找到对应的地址")

# 定义一个函数，用于解析身份证号码并提取信息
# idcard 是输入的身份证号码
def extract_idcard_info(idcard):
    # 检查身份证号码格式是否正确
    # 长度必须为18位，前17位必须是数字，最后一位可以是数字或 X/x
    if len(idcard) != 18 or not idcard[:-1].isdigit() or not idcard[-1] in "0123456789Xx":
        return "身份证号码格式不正确"

    # 提取出生日期
    birth_date_str = idcard[6:14]  # 从身份证号码中提取出生日期部分
    try:
        # 将出生日期字符串解析为日期对象
        birth_date = datetime.strptime(birth_date_str, "%Y%m%d").date()
    except ValueError:
        # 如果解析失败，说明出生日期不合法
        return "身份证号码中的出生日期不合法"

    # 提取性别
    # 身份证号码的第17位表示性别，奇数为男，偶数为女
    gender_code = int(idcard[16])
    gender = "男" if gender_code % 2 != 0 else "女"

    # 计算年龄
    today = datetime.today()  # 获取当前日期
    # 计算年龄，如果当前日期还未到出生日期的月份和日期，则年龄减一
    age = today.year - birth_date.year - ((today.month, today.day) < (birth_date.month, birth_date.day))

    # 获取身份证地址数据文件的路径
    file_path = get_resource_path('id_card_data.txt')
    # 加载身份证地址数据
    id_card_dict = load_id_card_data(file_path)
    # 提取身份证号码的前6位作为地址代码
    SSX_str = idcard[0:6]
    # 据地址代码查询地址
    address = query_address_by_code(SSX_str, id_card_dict)

    # 返回提取的信息
    return {
        "性别": gender,
        "年龄": age,
        "出生": birth_date.strftime("%Y%m%d"),
        "住址": address
    }

# 主程序入口
if __name__ == "__main__":
    # 检查命令行参数是否正确
    if len(sys.argv) != 2:
        print("用法：python information_From_ID_Numbers.py 身份证号码")
    else:
        # 获取输入的身份证号码
        input_Sn = sys.argv[1]
        # 解析身份证号码并提取信息
        info = extract_idcard_info(input_Sn)
        # 打印提取的信息
        print(info)